package com.qdu.springboot01cache.controller;

import com.qdu.springboot01cache.bean.Employee;
import com.qdu.springboot01cache.service.EmployeeService;
import com.qdu.springboot01cache.util.AjaxResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.Cache;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
@RequestMapping("/employee")
public class EmployeeController {
    @Autowired
    private EmployeeService employeeService;

    @Autowired
    RedisCacheManager cacheManager;

    //添加一个员工
    @RequestMapping("/insert")
    public AjaxResult insert(Employee employee){
        if (employeeService.insertSelective(employee)==1)
            return AjaxResult.successInstance("添加员工成功");
        else
            return AjaxResult.errorInstance("添加员工失败");
    }

    //根据员工id查询员工信息

    //讲方法的运行结果进行缓存，以后再使用相同的数据，直接从缓存中获取，不用调用方法
    //@Cacheable的几个属性
    //CacheManager管理多个Cache组件的，对缓存的真正的CRUD操作组件中,每一个缓存组件都由自己唯一的名字
    //1.cacheNames/value，指定缓存的名字
    //2.key:缓存数据使用的key：可以用它来指定。默认是方法参数的值
    //                        编写SpEl
    //#id;canshuid的值 #id 相当于 #root.args[0] #a0 #p0
    //3.keyGenerator:key的生成器，可以自己指定key的生成器组件
    //key/keyGenerator二选一
    //4.CacheManager：指定缓存管理器（可以指定redis）
    //CacheManager/CacheResolver(缓存解析器)二选一
    //5.condition:指定符合条件下才缓存
    //6.unless:否定缓存：当unless指定的条件为true，方法的返回指就不会缓存，可以获取到结果进行判断
    // unless与condition相反
    //sync:是否使用异步模式

    @RequestMapping("/selectById")
    @Cacheable(value = "emp"/*,keyGenerator = "myKeyGenerator" *//*,keyGenerator = "myKeyGenerator"*//*,condition = "#id>0",unless = "#result == null"*/)
    public AjaxResult selectById(Integer id){
        if (employeeService.selectByPrimaryKey(id)!=null) {
            System.out.println("查询的是姓名为"+
                    employeeService.selectByPrimaryKey(id).getLastname()+"的员工");
            return AjaxResult.successInstance(employeeService.selectByPrimaryKey(id));
        }
        else{
            System.out.println("查不到了！");
            return AjaxResult.errorInstance("没有此员工");}
    }

    //查询所有员工
    //通过代码方式进行缓存,与注解方式不同，方法是将方法返回值进行缓存
    @RequestMapping("/selectAll")
    public List<Employee> selectAll(){
        List<Employee> list = employeeService.selectAll();
        Cache cache = cacheManager.getCache("Employee");
        cache.put("list", list);
        return list;
    }

    //根据主键更新员工的信息
    //@CachePut：既调用方法，又更新缓存数据；同步更新缓存
    //  修改了数据库的某个数据，同时更新缓存；
    //  运行时机：
    //  1、先调用目标方法
    //  2、将目标方法的结果缓存起来
    @RequestMapping("/update")
    @CachePut(value = "emp",key = "#employee.id")
    public AjaxResult update(Employee employee){
        if (employeeService.updateByPrimaryKeySelective(employee)==1) {
            System.out.println("更新成功的员工是"+employee.getLastname());
            return AjaxResult.successInstance("更新成功");
        }
        else
            return AjaxResult.errorInstance("更新失败");
    }

    //根据主键删除员工
    //allEntries = true指定删除value = "emp"的所有缓存
    //beforeInvocation = false,缓存的清除是否在在方法之前执行，默认是在方法执行之后执行可在异常情况下不删除缓存
    @RequestMapping("/delete")
    @CacheEvict(value = "emp"/*,key = "#id"*/,allEntries = true)
    public AjaxResult delete(Integer id){
        if (employeeService.deleteByPrimaryKey(id)==1) {
            System.out.println("成功删除id为" + id + "的员工");
            return AjaxResult.successInstance("删除成功！");
        }
        else
            return AjaxResult.errorInstance("删除失败，请重试！");
    }

    //按照员工姓名查找员工（只查一个）
    @RequestMapping("/selectByLastName")
    // @Caching 定义复杂的缓存规则
    @Caching(
            cacheable = {
                    @Cacheable(value="emp",key = "#lastname")
            },
            put = {
//                    @CachePut(value="emp",key = "#result.id"),
                    @CachePut(value="emp",key = "#result.email")
            }
    )
    public Employee selectByLastName(String lastname){
        return employeeService.selectByLastName(lastname);
    }
}
